package org.tamal.classinfo;

import java.io.DataInputStream;
import java.io.IOException;

/**
 * This class represents an entry in Exception Table.
 * @author Tamal Kanti Nath
 */
public final class ExceptionEntry {

    private final ClassInfo cls;
    private int start;
    private int end;
    private int handler;
    private int catchTypeIndex;

    private ExceptionEntry(DataInputStream in, ClassInfo cls)
        throws IOException {
        this.cls = cls;
        start = in.readUnsignedShort();
        end = in.readUnsignedShort();
        handler = in.readUnsignedShort();
        catchTypeIndex = in.readUnsignedShort();
    }

    /**
     * Returns start_pc.
     * @return the start
     */
    public int getStart() {
        return start;
    }

    /**
     * Returns end_pc.
     * @return the end
     */
    public int getEnd() {
        return end;
    }

    /**
     * Returns handler_pc.
     * @return the handler
     */
    public int getHandler() {
        return handler;
    }

    /**
     * Returns catch Class index.
     * @return the catch type index
     */
    public int getCatchTypeIndex() {
        return catchTypeIndex;
    }

    /**
     * Returns catch Class.
     * @return the catch type
     */
    public String getCatchType() {
        return catchTypeIndex == 0 ? "finally"
                : cls.getPool()[catchTypeIndex].toString();
    }

    @Override
    public String toString() {
        return getCatchType();
    }

    /**
     * Reads Exception Table.
     * @param in The data input stream
     * @param cls The ClassInfo reference
     * @return the Exception table
     * @throws IOException exception
     * @see Code
     */
    static ExceptionEntry[] readExceptionTable(DataInputStream in,
        ClassInfo cls) throws IOException {
        ExceptionEntry[] table = new ExceptionEntry[in.readUnsignedShort()];
        for (int i = 0; i < table.length; ++i) {
            table[i] = new ExceptionEntry(in, cls);
        }
        return table;
    }
}
